package com.evan.review.anr;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.evan.review.R;

/**
 * 死锁ANR示例Activity
 * 演示因线程间死锁导致的ANR
 */
public class DeadlockActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "DeadlockANR";
    
    private Button btnSimpleDeadlock; // 简单死锁按钮
    private Button btnComplexDeadlock; // 复杂死锁按钮
    private TextView tvLogger; // 日志文本框
    private ScrollView svLogger; // 日志滚动视图
    
    // 两个锁对象，用于死锁演示
    private final Object lockA = new Object();
    private final Object lockB = new Object();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_deadlock);
        
        initViews(); // 初始化视图
        setListeners(); // 设置监听器
        
        logMessage("提示：点击按钮将引发不同类型的死锁ANR，请注意观察系统ANR对话框和日志输出");
        logMessage("死锁是由于两个或多个线程互相等待对方持有的锁而导致的永久阻塞状态");
    }
    
    /**
     * 初始化视图组件
     */
    private void initViews() {
        btnSimpleDeadlock = findViewById(R.id.btn_simple_deadlock);
        btnComplexDeadlock = findViewById(R.id.btn_complex_deadlock);
        tvLogger = findViewById(R.id.tv_logger);
        svLogger = findViewById(R.id.sv_logger);
    }
    
    /**
     * 设置监听器
     */
    private void setListeners() {
        btnSimpleDeadlock.setOnClickListener(this);
        btnComplexDeadlock.setOnClickListener(this);
    }
    
    @Override
    public void onClick(View v) {
        int id = v.getId();
        
        if (id == R.id.btn_simple_deadlock) {
            logMessage("开始执行简单死锁操作...");
            triggerSimpleDeadlock();
        } else if (id == R.id.btn_complex_deadlock) {
            logMessage("开始执行复杂死锁操作...");
            triggerComplexDeadlock();
        }
    }
    
    /**
     * 引发简单死锁导致的ANR
     * 主线程获取锁A，工作线程获取锁B，然后互相等待对方的锁
     */
    private void triggerSimpleDeadlock() {
        logMessage("创建简单的两线程死锁场景...");
        
        // 工作线程：先获取锁B，再尝试获取锁A
        Thread workerThread = new Thread(() -> {
            logMessage("工作线程启动，准备获取锁B");
            synchronized (lockB) {
                logMessage("工作线程获得锁B");
                
                // 暂停一下，确保主线程有机会获取锁A
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                logMessage("工作线程准备获取锁A");
                synchronized (lockA) {
                    logMessage("工作线程获得锁A（不会执行到这里）");
                }
            }
        });
        workerThread.start();
        
        // 暂停一下，确保工作线程有机会获取锁B
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 主线程：获取锁A，再尝试获取锁B，导致死锁
        logMessage("主线程准备获取锁A");
        synchronized (lockA) {
            logMessage("主线程获得锁A");
            
            // 暂停一下，增加死锁几率
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            logMessage("主线程准备获取锁B");
            synchronized (lockB) {
                logMessage("主线程获得锁B（不会执行到这里）");
            }
        }
        
        // 这里的代码不会被执行，因为已经死锁
        logMessage("死锁操作完成（不会执行到这里）");
    }
    
    /**
     * 引发复杂死锁导致的ANR
     * 创建多个线程，通过复杂的锁依赖关系形成循环等待
     */
    private void triggerComplexDeadlock() {
        logMessage("创建复杂的多线程死锁场景...");
        
        // 创建额外的锁对象
        final Object lockC = new Object();
        final Object lockD = new Object();
        
        // 线程1：获取锁A，然后尝试获取锁B
        Thread thread1 = new Thread(() -> {
            logMessage("线程1启动，准备获取锁A");
            synchronized (lockA) {
                logMessage("线程1获得锁A");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                logMessage("线程1准备获取锁B");
                synchronized (lockB) {
                    logMessage("线程1获得锁B（不会执行到这里）");
                }
            }
        });
        
        // 线程2：获取锁B，然后尝试获取锁C
        Thread thread2 = new Thread(() -> {
            logMessage("线程2启动，准备获取锁B");
            synchronized (lockB) {
                logMessage("线程2获得锁B");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                logMessage("线程2准备获取锁C");
                synchronized (lockC) {
                    logMessage("线程2获得锁C（不会执行到这里）");
                }
            }
        });
        
        // 线程3：获取锁C，然后尝试获取锁D
        Thread thread3 = new Thread(() -> {
            logMessage("线程3启动，准备获取锁C");
            synchronized (lockC) {
                logMessage("线程3获得锁C");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                logMessage("线程3准备获取锁D");
                synchronized (lockD) {
                    logMessage("线程3获得锁D（不会执行到这里）");
                }
            }
        });
        
        // 启动前三个线程
        thread1.start();
        thread2.start();
        thread3.start();
        
        // 主线程：获取锁D，然后尝试获取锁A，形成循环等待
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        logMessage("主线程准备获取锁D");
        synchronized (lockD) {
            logMessage("主线程获得锁D");
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            logMessage("主线程准备获取锁A");
            synchronized (lockA) {
                logMessage("主线程获得锁A（不会执行到这里）");
            }
        }
        
        // 这里的代码不会被执行，因为已经死锁
        logMessage("复杂死锁操作完成（不会执行到这里）");
    }
    
    /**
     * 记录日志信息到界面
     */
    private void logMessage(String message) {
        Log.d(TAG, message);
        
        new Handler(Looper.getMainLooper()).post(() -> {
            String currentText = tvLogger.getText().toString();
            String newText = currentText + "\n" + message;
            tvLogger.setText(newText);
            
            // 滚动到底部
            svLogger.post(() -> svLogger.fullScroll(View.FOCUS_DOWN));
        });
    }
} 